home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
biblio
/
bibtex
/
mac
/
macbibtex11.hqx
/
0.99c Sources
/
MacBibTeX 0.99c v1.1.sit
/
MacBibTex 0.99c V1.1
/
Pstr.c
< prev
next >
Wrap
Text File
|
1987-10-23
|
7KB
|
338 lines
/*
** Pascal string, C string, and formatting utility routines
**
** This module contains routines for
**
** + Copying, concatenating, and comparing Macintosh
** pascal-style (leading byte contains length) strings
**
** + Converting Macintosh pascal-style strings to/from C-style
** (NUL terminated) strings
**
** + Formatting numbers as pascal-style strings
**
** + Performing substitutions on pascal-style strings (formatting)
**
** Best of all, they're free!
**
** Written by Alan B. Mimms, 22 Oct, 1987
**
** Permission is hereby granted to freely duplicate, modify, disseminate,
** and otherwise distribute this software until your heart's content.
** No copyright is claimed. However, I am not responsible for the
** performance of this software and may not be held accountable for
** any failure of the software to perform in any way under any circum-
** stances.
*/
#include "Pstr.h"
/*
** Uncomment the following line and link with stdio and MacTraps
** (LightspeedC, anyway) to run the test stuff for numfmt ()...
**
** #define DEBUGMAIN
*/
/*
** Compare two pascal strings, returning a zero if they're equal,
** a negative number if s1 is less than s2, or
** a positive number if s1 is greater than s2.
*/
int pstrcmp (s1, s2)
register uchar *s1, *s2;
{
register int i;
register int c;
int len = *s1 < *s2 ? *s1 : *s2;
for (i = 1; i <= len; ++i)
if (c = s1 [i] - s2 [i]) return (c);
if (*s1 == *s2)
return (0);
else if (*s1 < *s2)
return (-1);
else
return (1);
}
/*
** Copy pascal string "s2" into the buffer to which "s1" points.
** NOTE: It is assumed that the buffer (s1) is large enough for
** the entire string "s2". Returns "s1".
*/
uchar *pstrcpy (s1, s2)
register uchar *s1, *s2;
{
register int i;
for (i = 0; i <= *s2; ++i) s1 [i] = s2 [i];
return (s1);
}
/*
** Concatenate the pascal string "s2" onto the end of the current
** contents of the pascal string "s1". Returns "s1".
*/
uchar *pstrcat (s1, s2)
register uchar *s1, *s2;
{
register int i;
for (i = 1; i <= s2 [0]; ++i)
s1 [++s1 [0]] = s2 [i];
return (s1);
}
/*
** Copy C-style (NUL terminated) string "c" to buffer to which "p"
** points as a pascal-style (leading byte contains length) string.
** Returns "p".
*/
uchar *cpyc2p (p, c)
register uchar *p, *c;
{
for (*p = 0; *c; ++c, ++*p)
p [*p] = *c;
return (p);
}
/*
** Copy pascal-style string "p" into buffer to which "c" points as a
** C-style string. Returns "c".
*/
uchar *cpyp2c (c, p)
register uchar *c, *p;
{
register int len;
uchar *oldc;
for (oldc = c, len = *p++; len; --len)
*c++ = *p++;
*c = 0;
return (oldc);
}
/*
** Format the number "n" in specified "radix" (2..16) using "width" as the
** desired field width. If "width" is greater than zero, leading
** blanks will be inserted to fill the result string to "width"
** bytes in length. If "width" is less than zero, the leading zeroes
** will be inserted instead of leading blanks. If "width" is zero,
** the minimum field width necessary to represent the value (i.e.,
** with no leading zeroes or leading blanks) will be used. If "radix"
** is zero, the default radix 10 will be used. Places the formatted
** number into the buffer to which "string" points (at least 34 bytes
** should be allocated for it -- you can use typedef "numbuf") as a
** pascal-style string. Returns "string".
*/
unsigned char *numfmt (string, n, width, radix)
register uchar *string;
register long n;
int width, radix;
{
register int w;
int wasneg, realwidth = width;
long realN = n;
static char digits [] = "0123456789ABCDEF";
if (!radix) radix = 10;
if (!width) width = 33;
string [0] = w = width < 0 ? -width : width;
if (wasneg = (n < 0)) {
n = -n;
wasneg = (width > 0);
}
for ( ; w; --w) {
uchar c = digits [n % radix];
if (!n && c == '0')
if (wasneg) {
c = '-';
wasneg = 0;
} else if (w != string [0] && width > 0) c = ' ';
string [w] = c;
n /= radix;
}
if (!realwidth) {
register int i, j;
for (i = 1; i < string [0]; ++i)
if (string [i] != ' ') break;
for (j = 1; i <= string [0]; ++i, ++j)
string [j] = string [i];
string [0] = j - 1;
} else if (n || wasneg)
for (w = 1; w <= string [0]; ++w)
string [w] = '*';
else if (realwidth < 0 && realN < 0)
string [1] = '-';
return (string);
}
/*
** Substitutes within the pascal-style string "result" the leftmost
** occurrence of the substring (pascal-style) "target" with the new
** substring (again, pascal-style) "source", and returns "result".
*/
uchar *mungpstr (result, target, source)
uchar *result, *target, *source;
{
register int r, delta;
/* Find position of target in result */
for (r = 1; r <= result [0] - target [0] + 1; ++r)
{
register int t;
for (t = 1; t <= target [0]; ++t)
if (target [t] != result [r + t - 1])
goto NotThisTime;
goto FoundTarget;
NotThisTime: ;
}
return (result); /* No target string found in result */
FoundTarget:
delta = source [0] - target [0];
if (delta > 0)
{
register int k;
for (k = result [0]; k >= r; --k)
result [k + delta] = result [k];
}
else if (delta < 0)
{
register int k;
for (k = r + source [0]; k <= result [0]; ++k)
result [k] = result [k - delta];
}
result [0] += delta;
for (delta = 1; delta <= source [0]; ++delta)
result [r++] = source [delta];
return (result);
}
/*
** Calls "mungpstr" repeatedly on the pascal-style string "msg"
** with successive pairs of parameters for the "target" and "source"
** strings. Calling sequence (in reality) is like this:
**
** Str255 buf;
** numbuf nbuf [34];
**
** mungmsg (
** pstrcpy (buf, "\PReplace foo with bar and X with a hex number"),
** "\Pfoo", "\Pbar",
** "\PX", numfmt (nbuf, 12345678L, 0, 16),
** (uchar *) 0);
**
** This call results in the string
**
** "Replace bar with bar and BC614E with a hex number"
*/
uchar *mungmsg (msg, mungitems)
uchar *msg, *mungitems;
{
register uchar **p;
for (p = &mungitems; *p; p += 2) mungpstr (msg, p [0], p [1]);
return (msg);
}
/*
** This is used during debugging...
*/
#ifdef DEBUGMAIN
#include <stdio.h>
/* Put out a pascal-style string to stdout */
static void putps (p)
char *p;
{
int i;
for (i = 1; i <= p [0]; ++i)
putchar (p [i]);
putchar ('\n');
}
#define TEST(v,w) numfmt(s,(v),(w),10);printf("%ld@%d=",(long)(v),(w));putps(s);
main ()
{
uchar s [256];
/* Test for faulty leading zero suppression */
TEST (-3000789L, -12);
TEST (-3000789L, 12);
TEST (-3000789L, 0);
TEST (3000789L, -12);
TEST (3000789L, 12);
TEST (3000789L, 0);
/* Test for correct display */
TEST (-123456789L, -12);
TEST (-123456789L, 12);
TEST (-123456789L, 0);
TEST (123456789L, -12);
TEST (123456789L, 12);
TEST (123456789L, 0);
TEST (0L, -12);
TEST (0L, 12);
TEST (0L, 0);
}
#endif DEBUGMAIN